package com.chuangke.sinotrukbudget.function;

import java.math.BigDecimal;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

import org.apache.commons.collections.CollectionUtils;

import com.chuangke.common.SpringContextUtil;
import com.chuangke.core.exception.ChuangkeException;
import com.chuangke.core.express.CkEvaluatorExecutor;
import com.chuangke.sinotrukbudget.model.BudgetBpcPlan;
import com.chuangke.sinotrukbudget.service.BudgetBpcPlanService;
import com.googlecode.aviator.AviatorEvaluator;
import com.googlecode.aviator.runtime.function.AbstractFunction;
import com.googlecode.aviator.runtime.type.AviatorDecimal;
import com.googlecode.aviator.runtime.type.AviatorObject;

public class BPCFunction extends AbstractFunction {

	private static final long serialVersionUID = 8205057364745422062L;

	public static void main(String[] args) {
		AviatorEvaluator.addFunction(new BPCFunction());

		CkEvaluatorExecutor.execute("BPC(a=3,b='a',c='43',d='rt')", null);

	}

	@Override
	public AviatorObject call(Map<String, Object> env, AviatorObject a1) {
		return call(env, null, null, null, null, null, null, null, null, null, null, null, null, null);
	}

	@Override
	public AviatorObject call(Map<String, Object> env, AviatorObject a1, AviatorObject a2) {
		return call(env, null, null, null, null, null, null, null, null, null, null, null, null, null);
	}

	@Override
	public AviatorObject call(Map<String, Object> env, AviatorObject a1, AviatorObject a2, AviatorObject a3) {
		return call(env, null, null, null, null, null, null, null, null, null, null, null, null, null);
	}

	@Override
	public AviatorObject call(Map<String, Object> env, AviatorObject a1, AviatorObject a2, AviatorObject a3,
			AviatorObject a4) {
		return call(env, null, null, null, null, null, null, null, null, null, null, null, null, null);
	}

	@Override
	public AviatorObject call(Map<String, Object> env, AviatorObject a1, AviatorObject a2, AviatorObject a3,
			AviatorObject a4, AviatorObject a5) {
		return call(env, null, null, null, null, null, null, null, null, null, null, null, null, null);
	}

	@Override
	public AviatorObject call(Map<String, Object> env, AviatorObject a1, AviatorObject a2, AviatorObject a3,
			AviatorObject a4, AviatorObject a5, AviatorObject a6) {
		return call(env, null, null, null, null, null, null, null, null, null, null, null, null, null);
	}

	@Override
	public AviatorObject call(Map<String, Object> env, AviatorObject a1, AviatorObject a2, AviatorObject a3,
			AviatorObject a4, AviatorObject a5, AviatorObject a6, AviatorObject a7) {
		return call(env, null, null, null, null, null, null, null, null, null, null, null, null, null);
	}

	@Override
	public AviatorObject call(Map<String, Object> env, AviatorObject a1, AviatorObject a2, AviatorObject a3,
			AviatorObject a4, AviatorObject a5, AviatorObject a6, AviatorObject a7, AviatorObject a8) {
		return call(env, null, null, null, null, null, null, null, null, null, null, null, null, null);
	}

	@Override
	public AviatorObject call(Map<String, Object> env, AviatorObject a1, AviatorObject a2, AviatorObject a3,
			AviatorObject a4, AviatorObject a5, AviatorObject a6, AviatorObject a7, AviatorObject a8,
			AviatorObject a9) {
		return call(env, null, null, null, null, null, null, null, null, null, null, null, null, null);
	}

	@Override
	public AviatorObject call(Map<String, Object> env, AviatorObject a1, AviatorObject a2, AviatorObject a3,
			AviatorObject a4, AviatorObject a5, AviatorObject a6, AviatorObject a7, AviatorObject a8, AviatorObject a9,
			AviatorObject a10) {
		return call(env, null, null, null, null, null, null, null, null, null, null, null, null, null);
	}

	@Override
	public AviatorObject call(Map<String, Object> env, AviatorObject a1, AviatorObject a2, AviatorObject a3,
			AviatorObject a4, AviatorObject a5, AviatorObject a6, AviatorObject a7, AviatorObject a8, AviatorObject a9,
			AviatorObject a10, AviatorObject a11) {
		return call(env, null, null, null, null, null, null, null, null, null, null, null, null, null);
	}

	@Override
	public AviatorObject call(Map<String, Object> env, AviatorObject a1, AviatorObject a2, AviatorObject a3,
			AviatorObject a4, AviatorObject a5, AviatorObject a6, AviatorObject a7, AviatorObject a8, AviatorObject a9,
			AviatorObject a10, AviatorObject a11, AviatorObject a12) {
		return call(env, null, null, null, null, null, null, null, null, null, null, null, null, null);
	}

	@Override
	public AviatorObject call(Map<String, Object> env, AviatorObject a1, AviatorObject a2, AviatorObject a3,
			AviatorObject a4, AviatorObject a5, AviatorObject a6, AviatorObject a7, AviatorObject a8, AviatorObject a9,
			AviatorObject a10, AviatorObject a11, AviatorObject a12, AviatorObject a13) {
		List<String> paramList = Arrays.asList("T_ENTITY", "T_CATEGORY", "T_AUDIT", "T_ACCOUNT", "T_TIME", "T_FLOW",
				"T_FLOW1", "T_FLOW2", "T_FLOW3", "T_FLOW4", "T_FLOW5", "T_FLOW6", "T_OBJECT");
		for (String param : paramList) {
			if (!env.keySet().contains(param)) {
				throw new ChuangkeException("未找到参数：" + param);
			}
		}

		BudgetBpcPlanService budgetBpcPlanService = (BudgetBpcPlanService) SpringContextUtil
				.getBean(BudgetBpcPlanService.class);

		List<BudgetBpcPlan> bbpList = budgetBpcPlanService.findBudgetBpcPlanByUniqueIndex(env);

		if (CollectionUtils.isEmpty(bbpList)) {
			String msg = String.format(
					"BPC函数计算(T_ACCOUNT=%s,T_FLOW=%s,T_FLOW1=%s)，计算结果:%s",
					env.get("T_ACCOUNT"),env.get("T_FLOW"), env.get("T_FLOW1"), "0");
			System.out.println(msg.replaceAll(",", "").replaceAll("=", "").replaceAll("\\.", "").replaceAll("_", ""));
			return new AviatorDecimal(new BigDecimal("0"));
		}

		if (bbpList.size() > 1) {
			String msg = String.format(
					"BPC函数计算异常(T_ENTITY=%s,T_CATEGORY=%s,T_AUDIT=%s,T_ACCOUNT=%s,T_TIME=%s,T_FLOW=%s,T_FLOW1=%s,T_FLOW2=%s,T_FLOW3=%s,T_FLOW4=%s,T_FLOW5=%s,T_FLOW6=%s,T_OBJECT=%s)，期望1个数据集，实际获取%d个数据集",
					env.get("T_ENTITY"), env.get("T_CATEGORY"), env.get("T_AUDIT"), env.get("T_ACCOUNT"),
					env.get("T_TIME"), env.get("T_FLOW"), env.get("T_FLOW1"), env.get("T_FLOW2"), env.get("T_FLOW3"),
					env.get("T_FLOW4"), env.get("T_FLOW5"), env.get("T_FLOW6"), env.get("T_OBJECT"), bbpList.size());
			throw new ChuangkeException(msg);
		}

		BigDecimal result = bbpList.get(0).getSigndata();
		
		String msg = String.format(
				"BPC函数计算(T_ACCOUNT=%s,T_FLOW=%s,T_FLOW1=%s)，计算结果:%s",
				env.get("T_ACCOUNT"),env.get("T_FLOW"), env.get("T_FLOW1"), result.toString());
		System.out.println(msg.replaceAll(",", "").replaceAll("=", "").replaceAll("\\.", "").replaceAll("_", ""));

		return new AviatorDecimal(result);
	}

	@Override
	public String getName() {
		return "BPC";
	}

}
